[[mvc-ann-controller-advice]]
= Controller Advice

[.small]#xref:web/webflux/controller/ann-advice.adoc[See equivalent in the Reactive stack]#

`@ExceptionHandler`, `@InitBinder`, and `@ModelAttribute` methods apply only to the
`@Controller` class, or class hierarchy, in which they are declared. If, instead, they
are declared in an `@ControllerAdvice` or `@RestControllerAdvice` class, then they apply
to any controller. Moreover, as of 5.3, `@ExceptionHandler` methods in `@ControllerAdvice`
can be used to handle exceptions from any `@Controller` or any other handler.

`@ControllerAdvice` is meta-annotated with `@Component` and therefore can be registered as
a Spring bean through xref:core/beans/java/instantiating-container.adoc#beans-java-instantiating-container-scan[component scanning]
. `@RestControllerAdvice` is meta-annotated with `@ControllerAdvice`
and `@ResponseBody`, and that means `@ExceptionHandler` methods will have their return
value rendered via response body message conversion, rather than via HTML views.

On startup, `RequestMappingHandlerMapping` and `ExceptionHandlerExceptionResolver` detect
controller advice beans and apply them at runtime. Global `@ExceptionHandler` methods,
from an `@ControllerAdvice`, are applied _after_ local ones, from the `@Controller`.
By contrast, global `@ModelAttribute` and `@InitBinder` methods are applied _before_ local ones.

The `@ControllerAdvice` annotation has attributes that let you narrow the set of controllers
and handlers that they apply to. For example:

[tabs]
======
Java::
+
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
----
	// Target all Controllers annotated with @RestController
	@ControllerAdvice(annotations = RestController.class)
	public class ExampleAdvice1 {}

	// Target all Controllers within specific packages
	@ControllerAdvice("org.example.controllers")
	public class ExampleAdvice2 {}

	// Target all Controllers assignable to specific classes
	@ControllerAdvice(assignableTypes = {ControllerInterface.class, AbstractController.class})
	public class ExampleAdvice3 {}
----

Kotlin::
+
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
----
	// Target all Controllers annotated with @RestController
	@ControllerAdvice(annotations = [RestController::class])
	class ExampleAdvice1

	// Target all Controllers within specific packages
	@ControllerAdvice("org.example.controllers")
	class ExampleAdvice2

	// Target all Controllers assignable to specific classes
	@ControllerAdvice(assignableTypes = [ControllerInterface::class, AbstractController::class])
	class ExampleAdvice3
----
======

The selectors in the preceding example are evaluated at runtime and may negatively impact
performance if used extensively. See the
{spring-framework-api}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]
javadoc for more details.




